#pragma once

#include <iostream>
#include <string>
#include <pthread.h>
#include <functional>


class Thread
{
public:
    // typedef void* (*func_t)(void* args);
    using func_t = std::function<void ()>;

    typedef enum{
        NEW = 0,
        RUNING,
        EXITED
    }ThreadStatus;

public:
    Thread(int num, func_t func)
    :_tid(0)
    ,_status(NEW)
    ,_func(func)
    
    {
        char name[128];
        snprintf(name, sizeof(name), "thread->%d", num);
        _name = name;
    }

    int threadStatus()
    {
        return _status;
    }

    std::string threadName()
    {
        return _name;
    }

    pthread_t threadID()
    {
        if(_status == RUNING)
        {
            return _tid;
        }
        else {
            std::cout << "该线程还没有运行！";
        }
        return 0;
    }

    static void* runHelper(void* args)
    {
        Thread *ts = (Thread*)args;

        (*ts)();
        return nullptr;
    }

    void operator ()()
    {
        if(_func != nullptr) _func();
    }

    void run()
    {
        int n = pthread_create(&_tid, nullptr, runHelper, this);
        if(n != 0)
        {
            std::cout << "线程运行失败！" << std::endl;
            exit(1);
        }
        _status = RUNING;
    }

    void join()
    {
        int n = pthread_join(_tid, nullptr);
        if(n != 0)
        {
            std::cout << "线程等待失败！" << std::endl;
            exit(1);
        }
        _status = EXITED;
    }

    ~Thread()
    {}

private:
    pthread_t _tid;
    std::string _name;
    func_t _func;
    ThreadStatus _status;


};